package com.umxwe.kill.es.utils;

import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.client.core.CountResponse;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.Scroll;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Component
@Slf4j
public class ElasticSearchUtil {

    @Autowired
    private RestHighLevelClient client;

    public final Integer SHARED_NUM =1;

    public final Integer REPLICAS_NUM =0;

    public final String DEFAULT_ANALYZER ="keyword";

    public Boolean checkIndexExist(String index)  {
        index = index.toLowerCase();
        GetIndexRequest request = new GetIndexRequest(index);
        boolean exists = false;
        try {
            exists = client.indices().exists(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("===== method checkIndexExist error, error message is ：{}",e.getMessage());
        }
        return exists;
    }

    public Boolean createIndex(String alias ,String index) {
        index = index.toLowerCase();
        if(checkIndexExist(index)){
            log.info("================已存在当前index：{}，直接返回",index);
            return true;
        }
        CreateIndexRequest request = new CreateIndexRequest(index);
        request.alias(new Alias(alias));
        request.settings(Settings.builder()
            .put("index.refresh_interval", "60s")
            .put("index.number_of_shards", SHARED_NUM)
            .put("index.number_of_replicas", REPLICAS_NUM)
            .put("analysis.analyzer.default.type", DEFAULT_ANALYZER)
        );
        try {
            client.indices().create(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("===== method createIndex error,error index is {}, error message is ：{}",index,e.getMessage());
            return false;
        }
        return true;
    }


    public <T> Map<String, Object> beanToMap(T bean) {
        Map<String, Object> map = new HashMap<>();
        if (bean != null) {
            BeanMap beanMap = BeanMap.create(bean);
            for (Object key : beanMap.keySet()) {
                map.put(key+"", beanMap.get(key));
            }
        }
        return map;
    }

    public void doChangeAlias(String alias, String oldIndex,String newIndex){
        IndicesAliasesRequest request = new IndicesAliasesRequest();
        IndicesAliasesRequest.AliasActions removeAction = new IndicesAliasesRequest.AliasActions(IndicesAliasesRequest.AliasActions.Type.REMOVE)
                .index(oldIndex)
                .alias(alias);
        IndicesAliasesRequest.AliasActions addAction = new IndicesAliasesRequest.AliasActions(IndicesAliasesRequest.AliasActions.Type.ADD)
                .index(newIndex)
                .alias(alias);
        request.addAliasAction(removeAction);
        request.addAliasAction(addAction);
        try {
            client.indices().updateAliases(request,RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("===== method doChangeAlias error, error message is ：{}",e.getMessage());
            e.printStackTrace();
        }
    }

    public long countIndex(String index){
        long count =0;
        CountRequest countRequest = new CountRequest(index);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        countRequest.source(searchSourceBuilder);
        try {
            CountResponse countResponse = client.count(countRequest, RequestOptions.DEFAULT);
            count = countResponse.getCount();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return count;
    }

    final Scroll scroll = new Scroll(TimeValue.timeValueMinutes(1L));

}
